<?php
/**
 *（Logic）
 */
namespace App\Logic\Amazon\Api;

class Authorize
{
    private const STATE_CACHE_KEY = 'Oauth-State-';

    private const STATE_CACHE_EXPIRED = 300;

    private const STATE_RANDOM = '-State-Random-';

    public function getSuccessRedirectUri(){
        return config('spapi.redirect_uri').'/authorized-callback';
    }

    /**
     * Amazon-spapi授权(合作伙伴API)
     * @param $sellerCentralUrl
     * @param $accountId
     * @return string
     * @throws \Exception
     */
    public function getOauthUrl($sellerCentralUrl,$accountId){
        $oauthUrl = $sellerCentralUrl.'/apps/authorize/consent?';
        $query = [];
        $query['application_id'] = config('spapi.application_id');
        $query['redirect_uri'] = config('spapi.redirect_uri').'/authorize-callback';
        $state = $this->_generateState($accountId);
        $query['state'] = $state;
        $query['version'] = 'beta';//测试
        return $oauthUrl . http_build_query($query);
    }

    /**
     * 计算状态参数
     * @param $accountId
     * @return string
     * @throws \Exception
     */
    private function _generateState($accountId){
        try{
            $str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!~@#$%^&*+';
            $len = strlen($str)-1;
            $random = $accountId.self::STATE_RANDOM;
            for($i = 0;$i < 50;$i++) {
                $random .= $str[mt_rand(0,$len)];
            }
            $random .= time();
            $state = encrypt($random);
            cache([self::STATE_CACHE_KEY.$accountId => $state], self::STATE_CACHE_EXPIRED);
            return $state;
        }catch (\Exception $e){
            throw new $e;
        }
    }

    /**
     * 解析状态参数
     * @param $state
     * @return array|null
     * @throws \Exception
     */
    public function parseState($state){
        if(!$state)return null;
        try{
            $random = decrypt($state);
            $accountId = substr($random,0,stripos($random,self::STATE_RANDOM));
            $cacheState = cache(self::STATE_CACHE_KEY.$accountId);
            return ['state' => $cacheState,'account_id' => $accountId];
        }catch (\Exception $e){
            throw new $e;
        }
    }
}
